home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src-glu / quadric.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-12  |  18.5 KB  |  752 lines

  1. /* $Id: quadric.c,v 1.2 1997/03/12 02:15:38 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: quadric.c,v $
  26.  * Revision 1.2  1997/03/12 02:15:38  brianp
  27.  * fixed problem in gluPartialDisk() reported by Kenneth H. Carpenter
  28.  *
  29.  * Revision 1.1  1996/09/27 01:19:39  brianp
  30.  * Initial revision
  31.  *
  32.  */
  33.  
  34.  
  35. /* TODO:
  36.  *   texture coordinate support
  37.  *   flip normals according to orientation
  38.  *   there's still some inside/outside orientation bugs in possibly all
  39.  *     but the sphere function
  40.  */
  41.  
  42.  
  43. #include <math.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include "gluP.h"
  47.  
  48.  
  49.  
  50. #ifndef M_PI
  51. #  define M_PI (3.1415926)
  52. #endif
  53.  
  54.  
  55. /*
  56.  * Convert degrees to radians:
  57.  */
  58. #define DEG_TO_RAD(A)   ((A)*(M_PI/180.0))
  59.  
  60.  
  61. /*
  62.  * Sin and Cos for degree angles:
  63.  */
  64. #define SIND( A )   sin( (A)*(M_PI/180.0) )
  65. #define COSD( A)    cos( (A)*(M_PI/180.0) )
  66.  
  67.  
  68. /*
  69.  * Texture coordinates if texture flag is set
  70.  */
  71. #define TXTR_COORD(x,y)    if (qobj->TextureFlag) glTexCoord2f(x,y);
  72.  
  73.  
  74.  
  75. struct GLUquadricObj {
  76.     GLenum    DrawStyle;        /* GLU_FILL, LINE, SILHOUETTE, or POINT */
  77.     GLenum Orientation;        /* GLU_INSIDE or GLU_OUTSIDE */
  78.     GLboolean TextureFlag;        /* Generate texture coords? */
  79.     GLenum Normals;        /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
  80.     void (*ErrorFunc)(GLenum err);    /* Error handler callback function */
  81. };
  82.  
  83.  
  84.  
  85. /*
  86.  * Process a GLU error.
  87.  */
  88. static void quadric_error( GLUquadricObj *qobj, GLenum error, const char *msg )
  89. {
  90.    /* Call the error call back function if any */
  91.    if (qobj->ErrorFunc) {
  92.       (*qobj->ErrorFunc)( error );
  93.    }
  94.    /* Print a message to stdout if MESA_DEBUG variable is defined */
  95.    if (getenv("MESA_DEBUG")) {
  96.       fprintf(stderr,"GLUError: %s: %s\n", gluErrorString(error), msg );
  97.    }
  98. }
  99.  
  100.  
  101.  
  102.  
  103. GLUquadricObj *gluNewQuadric( void )
  104. {
  105.    GLUquadricObj *q;
  106.  
  107.    q = (GLUquadricObj *) malloc( sizeof(struct GLUquadricObj) );
  108.    if (q) {
  109.       q->DrawStyle = GLU_FILL;
  110.       q->Orientation = GLU_OUTSIDE;
  111.       q->TextureFlag = GL_FALSE;
  112.       q->Normals = GLU_SMOOTH;
  113.       q->ErrorFunc = NULL;
  114.    }
  115.    return q;
  116. }
  117.  
  118.  
  119.  
  120. void gluDeleteQuadric( GLUquadricObj *state )
  121. {
  122.    if (state) {
  123.       free( (void *) state );
  124.    }
  125. }
  126.  
  127.  
  128.  
  129. /*
  130.  * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE, or GLU_POINT.
  131.  */
  132. void gluQuadricDrawStyle( GLUquadricObj *quadObject, GLenum drawStyle )
  133. {
  134.    if (quadObject && (drawStyle==GLU_FILL || drawStyle==GLU_LINE
  135.            || drawStyle==GLU_SILHOUETTE || drawStyle==GLU_POINT)) {
  136.       quadObject->DrawStyle = drawStyle;
  137.    }
  138.    else {
  139.       quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle" );
  140.    }
  141. }
  142.  
  143.  
  144.  
  145. /*
  146.  * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
  147.  */
  148. void gluQuadricOrientation( GLUquadricObj *quadObject, GLenum orientation )
  149. {
  150.    if (quadObject && (orientation==GLU_INSIDE || orientation==GLU_OUTSIDE)) {
  151.       quadObject->Orientation = orientation;
  152.    }
  153.    else {
  154.       quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation" );
  155.    }
  156. }
  157.  
  158.  
  159.  
  160. /*
  161.  * Set the error handler callback function.
  162.  */
  163. void gluQuadricCallback( GLUquadricObj *qobj,
  164.              GLenum which, void (*fn)(GLenum) )
  165. {
  166.    if (qobj && which==GLU_ERROR) {
  167.       qobj->ErrorFunc = fn;
  168.    }
  169. }
  170.  
  171.  
  172. void gluQuadricNormals( GLUquadricObj *quadObject, GLenum normals )
  173. {
  174.    if (quadObject
  175.          && (normals==GLU_NONE || normals==GLU_FLAT || normals==GLU_SMOOTH)) {
  176.       quadObject->Normals = normals;
  177.    }
  178. }
  179.  
  180.  
  181. void gluQuadricTexture( GLUquadricObj *quadObject,
  182.                 GLboolean textureCoords )
  183. {
  184.    if (quadObject) {
  185.       quadObject->TextureFlag = textureCoords;
  186.    }
  187. }
  188.  
  189.  
  190.  
  191.  
  192. /*
  193.  * Call glNormal3f after scaling normal to unit length.
  194.  */
  195. static void normal3f( GLfloat x, GLfloat y, GLfloat z )
  196. {
  197.    GLdouble mag;
  198.  
  199.    mag = sqrt( x*x + y*y + z*z );
  200.    if (mag>0.00001F) {
  201.       x /= mag;
  202.       y /= mag;
  203.       z /= mag;
  204.    }
  205.    glNormal3f( x, y, z );
  206. }
  207.  
  208.  
  209.  
  210. void gluCylinder( GLUquadricObj *qobj,
  211.                   GLdouble baseRadius, GLdouble topRadius, GLdouble height,
  212.                   GLint slices, GLint stacks )
  213. {
  214.    GLdouble da, r, dr, dz;
  215.    GLfloat x, y, z, nz, nsign;
  216.    GLint i, j;
  217.  
  218.    if (qobj->Orientation==GLU_INSIDE) {
  219.       nsign = -1.0;
  220.    }
  221.    else {
  222.       nsign = 1.0;
  223.    }
  224.  
  225.    da = 2.0*M_PI / slices;
  226.    dr = (topRadius-baseRadius) / stacks;
  227.    dz = height / stacks;
  228.    nz = (baseRadius-topRadius) / height;  /* Z component of normal vectors */
  229.  
  230.    if (qobj->DrawStyle==GLU_POINT) {
  231.       glBegin( GL_POINTS );
  232.       for (i=0;i<slices;i++) {
  233.      x = cos(i*da);
  234.      y = sin(i*da);
  235.      normal3f( x*nsign, y*nsign, nz*nsign );
  236.  
  237.      z = 0.0;
  238.      r = baseRadius;
  239.      for (j=0;j<=stacks;j++) {
  240.         glVertex3f( x*r, y*r, z );
  241.         z += dz;
  242.         r += dr;
  243.      }
  244.       }
  245.       glEnd();
  246.    }
  247.    else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
  248.       /* Draw rings */
  249.       if (qobj->DrawStyle==GLU_LINE) {
  250.      z = 0.0;
  251.      r = baseRadius;
  252.      for (j=0;j<=stacks;j++) {
  253.         glBegin( GL_LINE_LOOP );
  254.         for (i=0;i<slices;i++) {
  255.            x = cos(i*da);
  256.            y = sin(i*da);
  257.            normal3f( x*nsign, y*nsign, nz*nsign );
  258.            glVertex3f( x*r, y*r, z );
  259.         }
  260.         glEnd();
  261.         z += dz;
  262.         r += dr;
  263.      }
  264.       }
  265.       else {
  266.      /* draw one ring at each end */
  267.      if (baseRadius!=0.0) {
  268.         glBegin( GL_LINE_LOOP );
  269.         for (i=0;i<slices;i++) {
  270.            x = cos(i*da);
  271.            y = sin(i*da);
  272.            normal3f( x*nsign, y*nsign, nz*nsign );
  273.            glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
  274.         }
  275.         glEnd();
  276.         glBegin( GL_LINE_LOOP );
  277.         for (i=0;i<slices;i++) {
  278.            x = cos(i*da);
  279.            y = sin(i*da);
  280.            normal3f( x*nsign, y*nsign, nz*nsign );
  281.            glVertex3f( x*topRadius, y*topRadius, height );
  282.         }
  283.         glEnd();
  284.      }
  285.       }
  286.       /* draw length lines */
  287.       glBegin( GL_LINES );
  288.       for (i=0;i<slices;i++) {
  289.      x = cos(i*da);
  290.      y = sin(i*da);
  291.      normal3f( x*nsign, y*nsign, nz*nsign );
  292.      glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
  293.      glVertex3f( x*topRadius, y*topRadius, height );
  294.       }
  295.       glEnd();
  296.    }
  297.    else if (qobj->DrawStyle==GLU_FILL) {
  298.       GLfloat du = 1.0 / slices;
  299.       GLfloat dv = 1.0 / stacks;
  300.       GLfloat tcx = 0.0, tcy = 0.0;
  301.  
  302.       for (i=0;i<slices;i++) {
  303.      GLfloat x1 = -sin(i*da);
  304.      GLfloat y1 = cos(i*da);
  305.      GLfloat x2 = -sin((i+1)*da);
  306.      GLfloat y2 = cos((i+1)*da);
  307.      z = 0.0;
  308.      r = baseRadius;
  309.      tcy = 0.0;
  310.      glBegin( GL_QUAD_STRIP );
  311.      for (j=0;j<=stacks;j++) {
  312.         if (nsign==1.0) {
  313.            normal3f( x1*nsign, y1*nsign, nz*nsign );
  314.            TXTR_COORD(tcx, tcy);
  315.            glVertex3f( x1*r, y1*r, z );
  316.            normal3f( x2*nsign, y2*nsign, nz*nsign );
  317.            TXTR_COORD(tcx+du, tcy);
  318.            glVertex3f( x2*r, y2*r, z );
  319.         }
  320.         else {
  321.            normal3f( x2*nsign, y2*nsign, nz*nsign );
  322.            TXTR_COORD(tcx, tcy);
  323.            glVertex3f( x2*r, y2*r, z );
  324.            normal3f( x1*nsign, y1*nsign, nz*nsign );
  325.            TXTR_COORD(tcx+du, tcy);
  326.            glVertex3f( x1*r, y1*r, z );
  327.         }
  328.         z += dz;
  329.         r += dr;
  330.         tcy += dv;
  331.      }
  332.      glEnd();
  333.      tcx += du;
  334.       }
  335.    }
  336. }
  337.  
  338.  
  339.  
  340.  
  341.  
  342. void gluSphere( GLUquadricObj *qobj,
  343.                 GLdouble radius, GLint slices, GLint stacks )
  344. {
  345.    GLfloat rho, drho, theta, dtheta;
  346.    GLfloat x, y, z;
  347.    GLfloat s, t, ds, dt;
  348.    GLint i, j, imin, imax;
  349.    GLboolean normals;
  350.    GLfloat nsign;
  351.  
  352.    if (qobj->Normals==GLU_NONE) {
  353.       normals = GL_FALSE;
  354.    }
  355.    else {
  356.       normals = GL_TRUE;
  357.    }
  358.    if (qobj->Orientation==GLU_INSIDE) {
  359.       nsign = -1.0;
  360.    }
  361.    else {
  362.       nsign = 1.0;
  363.    }
  364.  
  365.    drho = M_PI / (GLfloat) stacks;
  366.    dtheta = 2.0 * M_PI / (GLfloat) slices;
  367.  
  368.    /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
  369.    /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
  370.    /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
  371.  
  372.    if (qobj->DrawStyle==GLU_FILL) {
  373.      if (!qobj->TextureFlag) {
  374.       /* draw +Z end as a triangle fan */
  375.       glBegin( GL_TRIANGLE_FAN );
  376.       glNormal3f( 0.0, 0.0, 1.0 );
  377.       TXTR_COORD(0.5,1.0);
  378.       glVertex3f( 0.0, 0.0, nsign * radius );
  379.       for (j=0;j<=slices;j++) {
  380.      theta = (j==slices) ? 0.0 : j * dtheta;
  381.      x = -sin(theta) * sin(drho);
  382.      y = cos(theta) * sin(drho);
  383.      z = nsign * cos(drho);
  384.      if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  385.      glVertex3f( x*radius, y*radius, z*radius );
  386.       }
  387.       glEnd();
  388.      }
  389.  
  390.       ds = 1.0 / slices;
  391.       dt = 1.0 / stacks;
  392.       t = 1.0;  /* because loop now runs from 0 */
  393.       if (qobj->TextureFlag) {
  394.         imin = 0;
  395.         imax = stacks;
  396.       }
  397.       else {
  398.         imin = 1;
  399.         imax = stacks-1;
  400.       }
  401.  
  402.       /* draw intermediate stacks as quad strips */
  403.       for (i=imin;i<imax;i++) {
  404.      rho = i * drho;
  405.      glBegin( GL_QUAD_STRIP );
  406.          s = 0.0;
  407.      for (j=0;j<=slices;j++) {
  408.         theta = (j==slices) ? 0.0 : j * dtheta;
  409.         x = -sin(theta) * sin(rho);
  410.         y = cos(theta) * sin(rho);
  411.         z = nsign * cos(rho);
  412.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  413.         TXTR_COORD(s,t);
  414.         glVertex3f( x*radius, y*radius, z*radius );
  415.         x = -sin(theta) * sin(rho+drho);
  416.         y = cos(theta) * sin(rho+drho);
  417.         z = nsign * cos(rho+drho);
  418.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  419.         TXTR_COORD(s,t-dt);
  420.             s += ds;
  421.         glVertex3f( x*radius, y*radius, z*radius );
  422.      }
  423.      glEnd();
  424.      t -= dt;
  425.       }
  426.  
  427.      if (!qobj->TextureFlag) {
  428.       /* draw -Z end as a triangle fan */
  429.       glBegin( GL_TRIANGLE_FAN );
  430.       glNormal3f( 0.0, 0.0, -1.0 );
  431.       TXTR_COORD(0.5,0.0);
  432.       glVertex3f( 0.0, 0.0, -radius*nsign );
  433.       rho = M_PI - drho;
  434.       s = 1.0;
  435.       t = dt;
  436.       for (j=slices;j>=0;j--) {
  437.      theta = (j==slices) ? 0.0 : j * dtheta;
  438.      x = -sin(theta) * sin(rho);
  439.      y = cos(theta) * sin(rho);
  440.      z = nsign * cos(rho);
  441.      if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  442.      TXTR_COORD(s,t);
  443.          s -= ds;
  444.      glVertex3f( x*radius, y*radius, z*radius );
  445.       }
  446.       glEnd();
  447.      }
  448.    }
  449.    else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
  450.       /* draw stack lines */
  451.       for (i=1;i<stacks;i++) {  /* stack line at i==stacks-1 was missing here */
  452.      rho = i * drho;
  453.      glBegin( GL_LINE_LOOP );
  454.      for (j=0;j<slices;j++) {
  455.         theta = j * dtheta;
  456.         x = cos(theta) * sin(rho);
  457.         y = sin(theta) * sin(rho);
  458.         z = cos(rho);
  459.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  460.         glVertex3f( x*radius, y*radius, z*radius );
  461.      }
  462.      glEnd();
  463.       }
  464.       /* draw slice lines */
  465.       for (j=0;j<slices;j++) {
  466.      theta = j * dtheta;
  467.      glBegin( GL_LINE_STRIP );
  468.      for (i=0;i<=stacks;i++) {
  469.         rho = i * drho;
  470.         x = cos(theta) * sin(rho);
  471.         y = sin(theta) * sin(rho);
  472.         z = cos(rho);
  473.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  474.         glVertex3f( x*radius, y*radius, z*radius );
  475.      }
  476.      glEnd();
  477.       }
  478.    }
  479.    else if (qobj->DrawStyle==GLU_POINT) {
  480.       /* top and bottom-most points */
  481.       glBegin( GL_POINTS );
  482.       if (normals)  glNormal3f( 0.0, 0.0, nsign );
  483.       glVertex3d( 0.0, 0.0, radius );
  484.       if (normals)  glNormal3f( 0.0, 0.0, -nsign );
  485.       glVertex3d( 0.0, 0.0, -radius );
  486.  
  487.       /* loop over stacks */
  488.       for (i=1;i<stacks-1;i++) {
  489.      rho = i * drho;
  490.      for (j=0;j<slices;j++) {
  491.         theta = j * dtheta;
  492.         x = cos(theta) * sin(rho);
  493.         y = sin(theta) * sin(rho);
  494.         z = cos(rho);
  495.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  496.         glVertex3f( x*radius, y*radius, z*radius );
  497.      }
  498.       }
  499.       glEnd();
  500.    }
  501.  
  502. }
  503.  
  504.  
  505.  
  506. void gluDisk( GLUquadricObj *qobj,
  507.               GLdouble innerRadius, GLdouble outerRadius,
  508.               GLint slices, GLint loops )
  509. {
  510.    GLdouble a, da;
  511.    GLfloat r, dr;
  512.    GLfloat x, y;
  513.    GLfloat r1, r2, dtc;
  514.    GLint s, l;
  515.  
  516.    /* Normal vectors */
  517.    if (qobj->Normals!=GLU_NONE) {
  518.       if (qobj->Orientation==GLU_OUTSIDE) {
  519.      glNormal3f( 0.0, 0.0, +1.0 );
  520.       }
  521.       else {
  522.      glNormal3f( 0.0, 0.0, -1.0 );
  523.       }
  524.    }
  525.  
  526.    da = 2.0*M_PI / slices;
  527.    dr = (outerRadius-innerRadius) / (GLfloat) loops;
  528.  
  529.    /* texture of a gluDisk is a cut out of the texture unit square */
  530.    /* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] (linear mapping) */
  531.    dtc = 2.0f * outerRadius;
  532.  
  533.    switch (qobj->DrawStyle) {
  534.       case GLU_FILL:
  535.      {
  536.          GLfloat sa,ca;
  537.          r1 = innerRadius;
  538.          for (l=0;l<loops;l++) {
  539.         r2 = r1 + dr;
  540.         if (qobj->Orientation==GLU_OUTSIDE) {
  541.            glBegin( GL_QUAD_STRIP );
  542.            for (s=0;s<=slices;s++) {
  543.           if (s==slices) a = 0.0;
  544.           else  a = s * da;
  545.           sa = sin(a); ca = cos(a);
  546.                   TXTR_COORD(0.5+sa*r2/dtc,0.5+ca*r2/dtc);
  547.                   glVertex2f( r2*sa, r2*ca );
  548.                   TXTR_COORD(0.5+sa*r1/dtc,0.5+ca*r1/dtc);
  549.                   glVertex2f( r1*sa, r1*ca );
  550.            }
  551.            glEnd();
  552.         }
  553.         else {
  554.            glBegin( GL_QUAD_STRIP );
  555.            for (s=slices;s>=0;s--) {
  556.           if (s==slices) a = 0.0;
  557.           else  a = s * da;
  558.           sa = sin(a); ca = cos(a);
  559.                   TXTR_COORD(0.5-sa*r2/dtc,0.5+ca*r2/dtc);
  560.                   glVertex2f( r2*sa, r2*ca );
  561.                   TXTR_COORD(0.5-sa*r1/dtc,0.5+ca*r1/dtc);
  562.                   glVertex2f( r1*sa, r1*ca );
  563.            }
  564.            glEnd();
  565.         }
  566.         r1 = r2;
  567.      }
  568.          }
  569.          break;
  570.       case GLU_LINE:
  571.      /* draw rings */
  572.      for (r=innerRadius; r<=outerRadius; r+=dr) {
  573.         glBegin( GL_LINE_LOOP );
  574.         for (a=0.0; a<2.0*M_PI; a+=da) {
  575.            glVertex2f( r*sin(a), r*cos(a) );
  576.         }
  577.         glEnd();
  578.      }
  579.      /* draw spokes */
  580.      for (a=0.0; a<2.0*M_PI; a+=da) {
  581.         x = sin(a);
  582.         y = cos(a);
  583.         glBegin( GL_LINE_STRIP );
  584.         for (r=innerRadius; r<=outerRadius; r+=dr) {
  585.            glVertex2f( r*x, r*y );
  586.         }
  587.         glEnd();
  588.      }
  589.      break;
  590.       case GLU_POINT:
  591.      glBegin( GL_POINTS );
  592.      for (a=0.0; a<2.0*M_PI; a+=da) {
  593.         x = sin(a);
  594.         y = cos(a);
  595.         for (r=innerRadius; r<=outerRadius; r+=dr) {
  596.            glVertex2f( r*x, r*y );
  597.         }
  598.      }
  599.      glEnd();
  600.      break;
  601.       case GLU_SILHOUETTE:
  602.      if (innerRadius!=0.0) {
  603.         glBegin( GL_LINE_LOOP );
  604.         for (a=0.0; a<2.0*M_PI; a+=da) {
  605.            x = innerRadius * sin(a);
  606.            y = innerRadius * cos(a);
  607.            glVertex2f( x, y );
  608.         }
  609.         glEnd();
  610.      }
  611.      glBegin( GL_LINE_LOOP );
  612.      for (a=0; a<2.0*M_PI; a+=da) {
  613.         x = outerRadius * sin(a);
  614.         y = outerRadius * cos(a);
  615.         glVertex2f( x, y );
  616.      }
  617.      glEnd();
  618.      break;
  619.       default:
  620.          abort();
  621.    }
  622. }
  623.  
  624.  
  625.  
  626. void gluPartialDisk( GLUquadricObj *qobj, GLdouble innerRadius,
  627.              GLdouble outerRadius, GLint slices, GLint loops,
  628.              GLdouble startAngle, GLdouble sweepAngle )
  629. {
  630.    if (qobj->Normals!=GLU_NONE) {
  631.       if (qobj->Orientation==GLU_OUTSIDE) {
  632.      glNormal3f( 0.0, 0.0, +1.0 );
  633.       }
  634.       else {
  635.      glNormal3f( 0.0, 0.0, -1.0 );
  636.       }
  637.    }
  638.  
  639.    if (qobj->DrawStyle==GLU_POINT) {
  640.       GLint loop, slice;
  641.       GLdouble radius, delta_radius;
  642.       GLdouble angle, delta_angle;
  643.       delta_radius = (outerRadius - innerRadius) / (loops-1);
  644.       delta_angle = DEG_TO_RAD((sweepAngle) / (slices-1));
  645.       glBegin( GL_POINTS );
  646.       radius = innerRadius;
  647.       for (loop=0; loop<loops; loop++) {
  648.      angle = DEG_TO_RAD(startAngle);
  649.      for (slice=0; slice<slices; slice++) {
  650.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  651.         angle += delta_angle;
  652.      }
  653.      radius += delta_radius;
  654.       }
  655.       glEnd();
  656.    }
  657.    else if (qobj->DrawStyle==GLU_LINE) {
  658.       GLint loop, slice;
  659.       GLdouble radius, delta_radius;
  660.       GLdouble angle, delta_angle;
  661.       delta_radius = (outerRadius - innerRadius) / loops;
  662.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  663.       /* draw rings */
  664.       radius = innerRadius;
  665.       for (loop=0; loop<loops; loop++) {
  666.      angle = DEG_TO_RAD(startAngle);
  667.      glBegin( GL_LINE_STRIP );
  668.      for (slice=0; slice<slices; slice++) {
  669.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  670.         angle += delta_angle;
  671.      }
  672.      glEnd();
  673.      radius += delta_radius;
  674.       }
  675.       /* draw spokes */
  676.       angle = DEG_TO_RAD(startAngle);
  677.       for (slice=0; slice<slices; slice++) {
  678.      radius = innerRadius;
  679.      glBegin( GL_LINE_STRIP );
  680.      for (loop=0; loop<loops; loop++) {
  681.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  682.         radius += delta_radius;
  683.      }
  684.      glEnd();
  685.      angle += delta_angle;
  686.       }
  687.    }
  688.    else if (qobj->DrawStyle==GLU_SILHOUETTE) {
  689.       GLint slice;
  690.       GLdouble angle, delta_angle;
  691.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  692.       /* draw outer ring */
  693.       glBegin( GL_LINE_STRIP );
  694.       angle = DEG_TO_RAD(startAngle);
  695.       for (slice=0; slice<=slices; slice++) {
  696.      glVertex2d( outerRadius * sin(angle), outerRadius * cos(angle) );
  697.      angle += delta_angle;
  698.       }
  699.       glEnd();
  700.       /* draw inner ring */
  701.       if (innerRadius>0.0) {
  702.      glBegin( GL_LINE_STRIP );
  703.      angle = DEG_TO_RAD(startAngle);
  704.      for (slice=0; slice<slices; slice++) {
  705.         glVertex2d( innerRadius * sin(angle), innerRadius * cos(angle) );
  706.         angle += delta_angle;
  707.      }
  708.      glEnd();
  709.       }
  710.       /* draw spokes */
  711.       if (sweepAngle<360.0) {
  712.      GLdouble stopAngle = startAngle + sweepAngle;
  713.      glBegin( GL_LINES );
  714.      glVertex2d( innerRadius*SIND(startAngle), innerRadius*COSD(startAngle) );
  715.      glVertex2d( outerRadius*SIND(startAngle), outerRadius*COSD(startAngle) );
  716.      glVertex2d( innerRadius*SIND(stopAngle), innerRadius*COSD(stopAngle) );
  717.      glVertex2d( outerRadius*SIND(stopAngle), outerRadius*COSD(stopAngle) );
  718.      glEnd();
  719.       }
  720.    }
  721.    else if (qobj->DrawStyle==GLU_FILL) {
  722.       GLint loop, slice;
  723.       GLdouble radius, delta_radius;
  724.       GLdouble angle, delta_angle;
  725.       delta_radius = (outerRadius - innerRadius) / loops;
  726.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  727.       radius = innerRadius;
  728.       for (loop=0; loop<loops; loop++) {
  729.      glBegin( GL_QUAD_STRIP );
  730.      angle = DEG_TO_RAD(startAngle);
  731.      for (slice=0; slice<slices; slice++) {
  732.         if (qobj->Orientation==GLU_OUTSIDE) {
  733.            glVertex2d( (radius+delta_radius)*sin(angle),
  734.                (radius+delta_radius)*cos(angle) );
  735.            glVertex2d( radius * sin(angle), radius * cos(angle) );
  736.         }
  737.         else {
  738.            glVertex2d( radius * sin(angle), radius * cos(angle) );
  739.            glVertex2d( (radius+delta_radius)*sin(angle),
  740.                (radius+delta_radius)*cos(angle) );
  741.         }
  742.         angle += delta_angle;
  743.      }
  744.      glEnd();
  745.      radius += delta_radius;
  746.       }
  747.    }
  748. }
  749.  
  750.  
  751.  
  752.